#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>
 
int main(int argc, char *argv[]) {
   int pipefd[2];
 
 
   if (argc != 2) {/* 파일명이 입력되었는지 아귀먼트 갯수 검사 */
      fprintf(stderr, "Usage: %s <string>\n", argv[0]);
      exit(EXIT_FAILURE); //exit()는 임플리멘테이션에 정의된 실패상태의 마침을 반환한다
   }
 
   char* input = argv[1]; // 명령줄인수의 첫번째 문자가 숫자인지 검사
 
   if (pipe(pipefd) == -1) {
      perror("pipe"); // 파이프를 생성한다.
      exit(EXIT_FAILURE);
   }
 
   pid_t cpid = fork(); // 자식 프로세스
   if (cpid == -1) {
      perror( "fork" ); // fork생성한다
      exit( EXIT_FAILURE );
   }
 
   if (cpid == 0) {
 
       char execOut[65540];
       close(pipefd[1]); // 사용하지않는다
 
       while(read(pipefd[0], execOut, sizeof(execOut)) != 0) //파일안의 있는 메모리를 읽는다.
       {
 
       }
 
       char grep[65540];
       sprintf(grep, "echo '%s' | grep %s", execOut, input); //메모리에 출력 하는 역활을 한다.
 
       FILE *p = popen(grep, "r"); //popen() 함수의 경우 실행 결과(STDOUT)가 파일 포인터 p에 저장이 된다.
 
       if (!p) // p의 부정
           puts("Error with grep"); //에러 메시지를 출력
 
       char line[1024];
       while(fgets(line, sizeof(line) - 1, p)) //p가 일정하면
       {
            puts(line); // 문자열 라인수 출력
       }
 
   } else {
 
       dup2(pipefd[1], 1); //파이프 입력쪽을 출력
       close(pipefd[0]);
       close(pipefd[1]);
       execl("/bin/ps", "ps", "aux", (char*)0);
       //명령을 실행할 수 없습니다
       char* errmsg = "Couldn't execute command"; //에러 메시지
       write(pipefd[1], errmsg, strlen(errmsg)); //표준 출력 함수
       close(pipefd[1]); //반환한다.
 
   }
 
   wait(&cpid); //cpid가 모두 종료될 때까지 기다리는 겁니다.
}

